package com.spzx.product.api;

import com.spzx.common.core.constant.SecurityConstants;
import com.spzx.common.core.constant.ServiceNameConstants;
import com.spzx.common.core.domain.R;
import com.spzx.product.api.domain.ProductSku;
import com.spzx.product.api.domain.SkuPriceVo;
import com.spzx.product.api.factory.RemoteProductFallbackFactory;
import io.swagger.v3.oas.annotations.Operation;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * 商品服务远程调用接口
 *
 * @author GAX
 * @date 2025-09-25
 */
@FeignClient(
        // value：指定需要远程调用的服务名，这里通过常量引用，实际值为 "spzx-product"
        value = ServiceNameConstants.PRODUCT_SERVICE,
        // path：指定提供方 Controller 的统一前缀，最终请求路径 = 服务地址 + 前缀 + 方法上的映射
        // path = "productSku",
        // fallbackFactory：指定远程调用的降级工厂。
        // 当上游调用下游发生异常（熔断、限流或网络错误）时，不再继续远程请求，
        // 而是直接调用本地定义的降级逻辑，保证调用方快速失败。
        fallbackFactory = RemoteProductFallbackFactory.class
)
// @FeignClient 注解会被 Spring 扫描并生成代理对象，
// 代理对象通过 RequestTemplate 发起 HTTP 请求。
// 根据配置，最终请求地址为： http://服务名(spzx-product)/{path}/接口URI。
// 服务名由 Nacos 注册中心解析为具体实例列表（IP + 端口）。
// 例如：192.168.12.130:9205、192.168.12.130:9105。
// Spring Cloud LoadBalancer 负责在实例间做负载均衡，默认采用轮询策略。
public interface RemoteProductService {
    @Operation(summary = "获取商品 SKU 详情")
    @GetMapping("productSku/getProductSku/{skuId}")
        // 注意：远程调用模块本身并不会引入业务模块的实体类，
        // 因此需要在 api 模块中维护一份共享的实体/DTO（如 ProductSku）。
        // 这样，调用方和提供方都依赖 api 模块，避免重复定义实体类。
    R<ProductSku> getProductSku(@PathVariable("skuId") Long skuId,
                                @RequestHeader(SecurityConstants.FROM_SOURCE) String source);


    @PostMapping(value = "productSku/getSkuPriceList")
    R<List<SkuPriceVo>> getSkuPriceList(
            @RequestBody List<Long> skuIdList,
            @RequestHeader(SecurityConstants.FROM_SOURCE) String source
    );

    @GetMapping(value = "productSku/getSkuPrice/{skuId}")
    R<SkuPriceVo> getSkuPrice(@PathVariable("skuId") Long skuId,
                              @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
}
